package com.itheima.user.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.common.enums.HttpCodeEnum;
import com.itheima.common.exception.LeadNewsException;
import com.itheima.common.util.AppJwtUtil;
import com.itheima.common.util.RequestContextUtil;
import com.itheima.common.vo.ResultVo;
import com.itheima.user.dto.LoginDto;
import com.itheima.user.dto.UserRelationDto;
import com.itheima.user.mapper.ApUserFanMapper;
import com.itheima.user.mapper.ApUserFollowMapper;
import com.itheima.user.pojo.ApUser;
import com.itheima.user.mapper.ApUserMapper;
import com.itheima.user.pojo.ApUserFan;
import com.itheima.user.pojo.ApUserFollow;
import com.itheima.user.service.ApUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.JwtBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @description <p>APP用户信息 业务实现</p>
 *
 * @version 1.0
 * @package com.itheima.user.service.impl
 */
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

    /**
     * app端用户登录业务处理
     *
     * @param loginDto 接收用户参数
     * @return 返回是否登录成功
     */
    @Override
    public ResultVo loginAuth(LoginDto loginDto) {
        //判断是否有手机，是账号登录还是，匿名登录
        ApUser apUser = new ApUser();
        //设置一个id为0，表示是匿名登录
        Long userId = 0L;
        //创建一个map集合封装返回给前端的数据
        Map<String,Object> loginMap = new HashMap<>();
        if (StringUtils.isEmpty(loginDto.getPhone())){
            //匿名登录，返回用户信息，和token
            loginMap.put("user",apUser);
            //更具用户id生成一个token发送给前端页面
            String token = AppJwtUtil.createToken(userId);
            //将用户对象和token封装到map集合中返回给前端页面
            loginMap.put("token",token);
            return ResultVo.ok(loginMap);
        }
        //进入这里表示是通过账号密码进行登录，更具手机号查询数据库
        apUser = query().eq("phone", loginDto.getPhone()).one();
        //判断查询到的用户对象是否为空，为空则表示没有此账号
        if (apUser==null||StringUtils.isEmpty(loginDto.getPassword())||StringUtils.isEmpty(loginDto.getPassword())){
            throw new LeadNewsException("账号密码错误");
        }
        //进入这里表示，该用户存在，且有账号密码，对密码进行加盐，加密
        String password = loginDto.getPassword();
        //对密码进行加盐
        password+=apUser.getSalt();
        //对密码进行加密
        String s = DigestUtils.md5DigestAsHex(password.getBytes());
        //将加密后的密码与查询到的用户密码进行校验
        if (!s.equals(apUser.getPassword())){
            throw new LeadNewsException("用户名或密码错误");
        }
        loginMap.put("user",apUser);
        //生成token，返回给前端
        String token = AppJwtUtil.createToken(apUser.getId());
        loginMap.put("token",token);
        //返回封装的数据
        return ResultVo.ok(loginMap);
    }
    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    /**
     * 关注作者与取消关注
     *
     * @param dto
     */
    @Override
    @Transactional
    public void userFollow(UserRelationDto dto) {
        //1. 判断当前用户是否是匿名用户
        if (RequestContextUtil.isAnonymous()) {
            // 需要登录后才能操作
            throw new LeadNewsException(HttpCodeEnum.NEED_LOGIN);
        }
        //2. 操作类型
        Integer operation = dto.getOperation();
        //3. 获取登录用户id
        Long loginUserId = RequestContextUtil.getUserId();
        //4. 获取作者id
        Long authorId = dto.getAuthorId();
        //5. 判断操作类型
        if(operation == 0){
            //5.1 取消关注
            // 删除关注记录
            removeFollow(loginUserId,authorId);
            // 删除粉丝记录
            removeFans(authorId,loginUserId);
        }else{
            //5.2 添加关注与粉丝
            // 判断是否关注过了，构建查询条件
            LambdaQueryWrapper<ApUserFollow> queryWrapper = Wrappers.<ApUserFollow>lambdaQuery()
                    .eq(ApUserFollow::getUserId, loginUserId)
                    .eq(ApUserFollow::getFollowId, authorId);
            ApUserFollow apUserFollow = apUserFollowMapper.selectOne(queryWrapper);
            if(null != apUserFollow){
                // 关注过了
                throw new LeadNewsException("已经关注过了!");
            }
            // 没关注过，
            // 查询登录用户信息
            ApUser loginUser = getById(loginUserId);
            // 查询作者信息
            ApUser author = getById(authorId);
            // 添加关注
            addFollow(loginUserId, author);
            // 添加粉丝
            addFans(authorId,loginUser);
        }
    }

    /**
     * 添加粉丝
     * @param authorId
     * @param loginUser
     */
    private void addFans(Long authorId, ApUser loginUser) {
        ApUserFan fans = new ApUserFan();
        fans.setUserId(authorId);
        fans.setFansId(loginUser.getId());
        fans.setFansName(loginUser.getName());
        fans.setLevel(0);
        fans.setCreatedTime(LocalDateTime.now());
        fans.setIsDisplay(1);
        fans.setIsShieldComment(0);
        fans.setIsShieldLetter(0);
        apUserFanMapper.insert(fans);
    }

    /**
     * 添加关注
     * @param loginUserId
     * @param author
     */
    private void addFollow(Long loginUserId, ApUser author) {
        ApUserFollow follow = new ApUserFollow();
        follow.setUserId(loginUserId);
        follow.setFollowId(author.getId());
        follow.setFollowName(author.getName());
        follow.setLevel(1);// 一般
        follow.setIsNotice(1); // 要通知
        follow.setCreatedTime(LocalDateTime.now());
        apUserFollowMapper.insert(follow);
    }

    /**
     * 删除关注关系
     * @param userId
     * @param followerId
     */
    private void removeFollow(Long userId, Long followerId){
        LambdaQueryWrapper<ApUserFollow> queryWrapper = Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getUserId, userId)
                .eq(ApUserFollow::getFollowId, followerId);
        apUserFollowMapper.delete(queryWrapper);
    }

    /**
     * 删除粉丝关系
     * @param userId
     * @param fansId
     */
    private void removeFans(Long userId, Long fansId){
        LambdaQueryWrapper<ApUserFan> queryWrapper = Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getUserId, userId)
                .eq(ApUserFan::getFansId, fansId);
        apUserFanMapper.delete(queryWrapper);
    }
}
